////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

// Στο παρόν module υπάρχουν services σχετικά με τις ενέργειες που
// αποστέλλουν οι clients.

Log.print('service module: energia');

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

// Τα σχετικά με τις υπηρεσίες που ορίζονται στο παρόν module εντάσσονται στο
// singleton "energia" το οποίο χρησιμοποιείται ως name space.

Service.energia = {};

// Η function "exec" χρησιμοποιείται ως εκκινητής των καθαυτό functions διαχείρισης
// ενεργειών. Εκτελούνται βασικοί έλεγχοι που είναι κοινοί σε όλους τις functions
// διαχείρισης, και κατόπιν καλείται η καθαυτό function διαχείρισης με παραμέτρους
// το αίτημα, το url, τη συνεδρία τού αποστολέα και το τραπέζι.

Service.energia.exec = function(nodereq, callback) {
	if (nodereq.isvoli()) return;
	if (nodereq.oxiTrapezi()) return;
	if (!nodereq.url.hasOwnProperty('trapezi')) return nodereq.end('Ενέργεια σε ακαθόριστο τραπέζι');
	if (nodereq.url.trapezi != nodereq.trapezi.kodikos) return nodereq.end('Ενέργεια σε ξένο τραπέζι');
	if (nodereq.sinedria.oxiPektis()) return nodereq.end('Δεν είστε παίκτης του τραπεζιού');
	if (nodereq.trapezi.epomenos != nodereq.sinedria.thesi) return nodereq.end('Ενέργεια εκτός σειράς');
	callback(nodereq, nodereq.url, nodereq.sinedria, nodereq.trapezi);
}

Service.energia.apostoli = function(trapezi, sinedria, energia) {
	(new Kinisi({
		'?': 'EG',
		't': trapezi.kodikos,
		'p': sinedria.thesi,
		'i': Prefadoros.energiaIdosEco(energia.idos),
		'd': energia.data,
	})).kinisiAdd();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

Service.energia.dilosi = function(req) {
	Service.energia.exec(req, Service.energia.dilosi1);
}

Service.energia.dilosi1 = function(req, url, sinedria, trapezi) {
	var dianomi, i, teleftea, dilosi = {}, energia, paso = 0;

	if (trapezi.fasi != 'ΔΗΛΩΣΗ') return req.end('Δεν είναι ώρα δηλώσεων');

	// Κατασκευάζουμε τώρα ενέργεια για τη δήλωση που παραλάβαμε από τον client.
	// Ξεκινάμε με ανάθεση των βασικών properties της εν λόγω ενέργειας.

	energia = new Energia({
		idos: 'ΔΗΛΩΣΗ',
		pektis: sinedria.thesi,
	});

	// Τώρα θα αποκωδικοποιήσουμε τη δήλωση και θα θέσουμε αναλόγως το property
	// "data" της ενέργειας που κατασκευάζουμε.

	// Εξετάζουμε πρώτα την περίπτωση "ΑΜΑ ΜΕΙΝΟΥΝ".

	if (url.hasOwnProperty('grafio')) energia.data = 'DTG';

	// Κατόπιν ελέγχουμε την περίπτωση "ΠΑΣΟ". Εδώ θα πρέπει να συμπληρώσουμε
	// το ύψος της δήλωσης. Αν δεν έχει προηγηθεί άλλη δήλωση, το πάσο δηλώθηκε
	// στο ύψος "ΑΜΑ ΜΕΙΝΟΥΝ", αλλιώς το πάσο δηλώθηκε στο ύψος της πρότασης που
	// ακολουθεί την προηγούμενη δήλωση.

	else if (url.hasOwnProperty('paso')) energia.data = trapezi.agora ?
		trapezi.agora.epomeniDilosi().setPaso().dilosi2string() : 'PTG';

	// Τέλος, μένει η περίπτωση στην οποία έχει δηλωθεί χρώμα και μπάζες.

	else {
		if (!url.hasOwnProperty('xroma')) return req.end('Ακαθόριστο χρώμα δήλωσης');
		if (!Agora.xroma.hasOwnProperty(url.xroma)) return req.end('Λάθος χρώμα δήλωσης');

		if (!url.hasOwnProperty('bazes')) return req.end('Ακαθόριστες μπάζες δήλωσης');
		if (!Agora.bazes.hasOwnProperty(url.bazes)) return req.end('Λάθος μπάζες δήλωσης');

		energia.data = (url.hasOwnProperty('edo') ? 'E' : 'D') + url.xroma + Agora.bazes[url.bazes];
	}

	// Στο σημείο αυτό το αίτημα έχει ελεγχθεί και βρέθηκε αποδεκτό.

	req.end();

	// Εισάγουμε την ενέργεια στην τελευταία διανομή του τραπεζιού και
	// ενημερώνουμε τους clients που σχετίζονται με το τραπέζι.

	trapezi.energiaAdd(energia);

	// Ανάλογα με τη φάση στην οποία περιέρχεται το τραπέζι μετά την προσθήκη
	// της συγκεκριμένης ενέργειας, εμπλουτίζουμε τα data της ενέργειας αυτής
	// με επιπλέον πληροφορία.

	switch (trapezi.fasi) {

	// Στην περίπτωση που το τραπέζι έχει περιέλθει σε κατάσταση "FLOP", δηλαδή
	// σε φάση κατά την οποία οι clients θα παρουσιάσουν τον τζόγο, στον server
	// δρομολογείται νέα διανομή σε εύλογο χρονικό διάστημα. Για λόγους ασφάλειας
	// και ειδικά στον server, αλλάζουμε τη φάση του τραπεζιού σε "FLOP_WAIT" που
	// δείχνει ακριβώς αυτό, δηλαδή ότι έχει δρομολογηθεί νέα διανομή μετά από τρία
	// πάσο. Κατόπιν προχωρούμε στον εμπλουτισμό των δεδομένων της ενέργειας με τα
	// φύλλα τού τζόγου.

	case 'FLOP':
		trapezi.fasi = 'FLOP_WAIT';
		energia.data += ':' + trapezi.tzogos.toString();
		setTimeout(function() {
			trapezi.neaDianomi(trapezi.dealer.epomenosPektis());
		}, 3000);
		break;

	// Συνεχίζουμε με την περίπτωση της αλλαγής στην οποία επίσης θα πρέπει να
	// εμπλουτίσουμε τα δεδομένα της ενέργειας με τα φύλλα του τζόγου. Βεβαίως,
	// αυτά τα δεδομένα θα φιλτραριστούν κατά την αποστολή ώστε να μην αποσταλεί
	// ο τζόγος στους αντιπάλους.

	case 'ΑΛΛΑΓΗ':
		energia.data += ':' + trapezi.tzogos.toString();
		trapezi.fila[trapezi.tzogadoros].addXartosia(trapezi.tzogos);
		break;
	}

	Service.energia.apostoli(trapezi, sinedria, energia);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

Service.energia.solo = function(req) {
	Service.energia.exec(req, Service.energia.solo1);
}

Service.energia.solo1 = function(req, url, sinedria, trapezi) {
	if (trapezi.fasi != 'ΑΛΛΑΓΗ') return req.end('Σολαρία εκτός σειράς');
	if (!url.hasOwnProperty('agora')) return req.end('Ακαθόριστη αγορά σολαρίας');
	req.end();

	// Κατασκευάζουμε τώρα ενέργεια για το αίτημα σολαρίας που παραλάβαμε από τον
	// client. Ξεκινάμε με ανάθεση των βασικών properties της εν λόγω ενέργειας.

	energia = new Energia({
		idos: 'ΣΟΛΟ',
		pektis: sinedria.thesi,
		data: url.agora,
	});

	// Εισάγουμε την ενέργεια στην τελευταία διανομή του τραπεζιού και
	// ενημερώνουμε τους clients που σχετίζονται με το τραπέζι.

	trapezi.energiaAdd(energia);
	Service.energia.apostoli(trapezi, sinedria, energia);

	// Πρόκειται να δρομολογήσουμε νέα διανομή. Μέχρι να γίνει η νέα διανομή,
	// ειδικά στον server, αλλάζουμε τη φάση του τραπεζιού σε "ΣΟΛΟ_WAIT".

	trapezi.fasi = 'ΣΟΛΟ_WAIT';
	setTimeout(function() {
		trapezi.neaDianomi(trapezi.dealer.epomenosPektis());
	}, 5000);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

Service.energia.agora = function(req) {
	Service.energia.exec(req, Service.energia.agora1);
}

Service.energia.agora1 = function(req, url, sinedria, trapezi) {
	var skarta, i, agora;

	if (trapezi.fasi != 'ΑΛΛΑΓΗ') return req.end('Αγορά εκτός σειράς');
	if (!url.hasOwnProperty('xroma')) return req.end('Ακαθόριστη χρώμα αγοράς');
	if (!Agora.xroma.hasOwnProperty(url.xroma)) return req.end(url.xroma + ': απροσδιόριστο χρώμα αγοράς');
	if (!url.hasOwnProperty('bazes')) return req.end('Ακαθόριστες μπάζες αγοράς');
	if (!Agora.bazes.hasOwnProperty(url.bazes)) return req.end(url.bazes + ': απροσδιόριστες μπάζες αγοράς');

	if (!url.hasOwnProperty('skarta')) return req.end('Ακαθόριστα σκάρτα αγοράς');
	skarta = url.skarta.toXartosia();
	if (skarta.fila.length != 2) return req.end(url.skarta + ': απροσδιόριστα σκάρτα αγοράς');
	req.end();

	agora = new Agora({
		xroma: url.xroma,
		bazes: parseInt(url.bazes),
	});
	if (url.hasOwnProperty('asoi')) agora.setAsoi();

	// Κατασκευάζουμε τώρα ενέργεια που αντανακλά την υποβολή αγοράς.

	energia = new Energia({
		idos: 'ΑΓΟΡΑ',
		pektis: sinedria.thesi,
		data: agora.agora2string() + ':' + skarta.toString(),
	});

	// Εισάγουμε την ενέργεια στην τελευταία διανομή του τραπεζιού και
	// ενημερώνουμε τους clients που σχετίζονται με το τραπέζι.

	trapezi.energiaAdd(energia);
	Service.energia.apostoli(trapezi, sinedria, energia);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

Service.energia.simetoxi = function(req) {
	Service.energia.exec(req, Service.energia.simetoxi1);
}

Service.energia.simetoxi1 = function(req, url, sinedria, trapezi) {
	var energia;

	switch (trapezi.fasi) {
	case 'ΣΥΜΜΕΤΟΧΗ1':
	case 'ΣΥΜΜΕΤΟΧΗ2':
	case 'ΣΥΜΜΕΤΟΧΗ3':
		break;
	default:
		return req.end('Δεν είναι ώρα δηλώσεων συμμετοχής');
	}

	if (!url.hasOwnProperty('simetoxi')) return req.end('Ακαθόριστος τρόπος συμμετοχής');
	req.end();

	// Κατασκευάζουμε τώρα ενέργεια για τη δήλωση που παραλάβαμε από τον client.
	// Ξεκινάμε με ανάθεση των βασικών properties της εν λόγω ενέργειας.

	energia = new Energia({
		idos: 'ΣΥΜΜΕΤΟΧΗ',
		pektis: sinedria.thesi,
		data: url.simetoxi,
	});

	// Εισάγουμε την ενέργεια στην τελευταία διανομή του τραπεζιού και
	// ενημερώνουμε τους clients που σχετίζονται με το τραπέζι.

	trapezi.energiaAdd(energia);
	Service.energia.apostoli(trapezi, sinedria, energia);
}
